#include "GUIPrinter.h"
#include "MapGen.h"
#include "QLearningAlgorithm.h"
#include <iostream>
#include "Macros.h"
#include <windows.h>

using namespace std;

GUIPrinter::GUIPrinter(MapGen *mapgen, QLearningAlgorithm *qa) :
    m_pMapGen(mapgen),
    m_pQLearningAlgorithm(qa)
{

}

GUIPrinter::~GUIPrinter()
{

}

void GUIPrinter::printMap(char map[ROOM_WIDTH][ROOM_HEIGHT])
{
    for(int i = 0; i < ROOM_WIDTH; ++i)
    {
        for(int j = 0; j < ROOM_HEIGHT; ++j)
        {
            switch(map[i][j])
            {
            case '@':
                setConsoleColor(BLUE);
                cout << map[i][j];
                setConsoleColor(WHITE);
                break;
            case '0':
                setConsoleColor(GREEN);
                cout << map[i][j];
                setConsoleColor(WHITE);
                break;
            case 'M':
                setConsoleColor(RED);
                cout << map[i][j];
                setConsoleColor(WHITE);
                break;
            case 'T':
                setConsoleColor(YELLOW);
                cout << map[i][j];
                setConsoleColor(WHITE);
                break;
            default:
                cout << map[i][j];
                break;
            }
        }
        cout << endl;
    }
}

void GUIPrinter::showMapWithPlayer()
{
    int px = m_pMapGen->m_ini_player_x;
    int py = m_pMapGen->m_ini_player_y;
    m_pMapGen->m_map[px][py] = '@';
    printMap(m_pMapGen->m_map);
    cout << endl << "Map Generated!!!\n"
                    "Index:\n"
                    "WALL      #\n"
                    "FLOOR     .\n";
    setConsoleColor(RED);
    cout << "MONSTER   M\n";
    setConsoleColor(WHITE);
    setConsoleColor(GREEN);
    cout << "EXIT      0\n";
    setConsoleColor(WHITE);
    setConsoleColor(BLUE);
    cout << "PLAYER    @\n";
    setConsoleColor(WHITE);
    setConsoleColor(YELLOW);
    cout << "TREASURE  T\n";
    setConsoleColor(WHITE);
    cout << "Press ENTER to continue...\n" << endl;
    cin.get();
    m_pMapGen->m_map[px][py] = '.';
    system("cls");
}

void GUIPrinter::printQHash()
{
    for(auto iter = m_pQLearningAlgorithm->hashQ.begin();
        iter != m_pQLearningAlgorithm->hashQ.end(); ++iter)
    {
        int index = iter.key();
        cout << index << "   ";
        for(auto jt = iter.value().begin(); jt != iter.value().end(); ++jt)
        {
            cout << *jt << "     ";
        }
        cout << endl;
    }
    cout << endl;
    cin.get();
    system("cls");
}

void GUIPrinter::runSim()
{
    //run sim using Q table
    int player_x = m_pMapGen->m_ini_player_x;
    int player_y = m_pMapGen->m_ini_player_y;
    char copymap[ROOM_WIDTH][ROOM_HEIGHT];
    memcpy(copymap, m_pMapGen->m_map, ROOM_WIDTH * ROOM_HEIGHT * sizeof(char));
    while(copymap[player_x][player_y] != '0')
    {
        copymap[player_x][player_y] = '@';
        printMap(copymap);
        Sleep(500);
        system ("cls");
        copymap[player_x][player_y] = '.';

        int playerstate_i = ROOM_WIDTH*player_x + player_y;
        //find dir, can go and max q
        int dir = m_pQLearningAlgorithm->maxQDir(playerstate_i);
        int nextstate_i = m_pQLearningAlgorithm->vecstates[playerstate_i].m_transfer.find(dir).value();

        player_x = m_pQLearningAlgorithm->vecstates[nextstate_i].m_x;
        player_y = m_pQLearningAlgorithm->vecstates[nextstate_i].m_y;
    }
    copymap[player_x][player_y] = '@';
    printMap(copymap);
    cout << endl << "Player has arrived destiny!" << endl;
    cin.get();
    system("cls");
}

void GUIPrinter::setConsoleColor(enConsoleColor color)
{
    switch(color)
    {
    case RED: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
        break;
    case GREEN: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
        break;
    case BLUE: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
        break;
    case YELLOW: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED|FOREGROUND_GREEN);
        break;
    case WHITE: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
        break;
    }
}
